#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <unistd.h>
#include <time.h>
#include <pthread.h>

#define BUFLEN      (1024)
#define THREADNUM   (3)

/*互斥量*/
pthread_mutex_t ALOCK = PTHREAD_MUTEX_INITIALIZER;

static void *handle_thread(void *argv)
{
    int sockfd = *((int *)argv);    
    int newfd;
    struct sockaddr_in c_addr;
    socklen_t len;
    char buf[BUFLEN];
    time_t now;

    while(1){
        len = sizeof(struct sockaddr);
        /*拒绝客户端的请求*/
        pthread_mutex_lock(&ALOCK);

        if ((newfd = accept(sockfd,(struct sockaddr *)&c_addr, &len)) == -1) {
            perror("accept");        
            exit(errno);
        } else {
            printf("\n*****************通信开始***************\n");
            printf("正在与您通信的客户端是：%s: %d\n", inet_ntoa(c_addr.sin_addr),
                                                        ntohs(c_addr.sin_port));
        }
        /*接受客户端的请求*/
        pthread_mutex_unlock(&ALOCK);
        /*处理客户端请求*/
        bzero(buf, BUFLEN);
        len = recv(newfd, buf, BUFLEN, 0);
        if (len > 0 && !strncmp(buf, "TIME", 4)) {
            bzero(buf, BUFLEN);
            /*获取系统当前时间*/
            now = time(NULL);
            /*ctime将系统时间转换为字符串，sprintf使转化后的字符串保存在buf*/
            sprintf(buf, "%24s\r\n", ctime(&now));
            /*发送系统时间*/
            send(newfd, buf, strlen(buf), 0);
        }
        /*关闭通讯的套接字*/
        close(newfd);
    }

    return NULL;
}

int main(int argc, char **argv)
{
    int sockfd, i;
    struct sockaddr_in s_addr;
    unsigned int port, listnum;
    pthread_t thread_s[THREADNUM];
    
    /*建立socket*/
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(errno);
    } else
        printf("socket create success!\n");

    /*设置服务器端口*/    
    if (argv[2])
        port = atoi(argv[2]);
    else
        port = 4567;

    /*设置侦听队列长度*/
    if (argv[3])
        listnum = atoi(argv[3]);
    else
        listnum = 3;

    /*设置服务器ip*/
    bzero(&s_addr, sizeof(s_addr));
    s_addr.sin_family = AF_INET;
    s_addr.sin_port = htons(port);
    if (argv[1])
        s_addr.sin_addr.s_addr = inet_addr(argv[1]);
    else
        /*INADDR_ANY就是指定地址为0.0.0.0的地址*/
        s_addr.sin_addr.s_addr = INADDR_ANY;

    /*把地址和端口帮定到套接字上*/
    if((bind(sockfd, (struct sockaddr *)&s_addr, sizeof(struct sockaddr))) == -1){
        perror("bind");
        exit(errno);
    } else
        printf("bind success!\n");

    /*侦听本地端口*/
    if (listen(sockfd, listnum) == -1){
        perror("listen");
        exit(errno);    
    } else
        printf("the server is listening!\n");

    /*处理客户端的连接*/
    for (i = 0; i < THREADNUM; i++) {
        /*创建线程来处理连接*/
        pthread_create(&thread_s[i], NULL, handle_thread, (void *)&sockfd);
    }

    /*等待线程结束*/
    for (i = 0; i < THREADNUM; i++) {
        pthread_join(thread_s[i], NULL);
    }

    /*关闭服务器的套接字*/
    close(sockfd);
    return 0;
}